#include <string>
#include <iostream>
#include <vector>
#include "smartptr.hpp"
using namespace std;
void test_unique_ptr()
{
	chy::unique_ptr<A> up1(new A);
	//chy::unique_ptr<A> up2(up1);
	up1->_a1++;
	up1->_a2++;

	chy::unique_ptr<A> up3(new A);
	//up1 = up2;
}
void test_auto_ptr()
{
	chy::auto_ptr<A> ap1(new A);
	ap1->_a1++;
	ap1->_a2++;

	chy::auto_ptr<A> ap2(ap1);
	//ap1->_a1++;
	//ap1->_a2++;
	ap2->_a1++;
	ap2->_a2++;

	// 2 2
	cout << ap2->_a1 << endl;
	cout << ap2->_a2 << endl;

	chy::auto_ptr<A> ap3(new A);
	ap2 = ap3;

	ap2->_a1++;
	ap2->_a2++;

	cout << ap2->_a1 << endl;
	cout << ap2->_a2 << endl;
}
void test_shared_ptr1()
{
	chy::shared_ptr<A> sp1(new A);
	chy::shared_ptr<A> sp2(sp1);
	chy::shared_ptr<A> sp3(sp1);

	sp1->_a1++;
	sp1->_a2++;
	cout << sp2->_a1 << ":" << sp2->_a2 << endl;
	sp2->_a1++;
	sp2->_a2++;
	cout << sp1->_a1 << ":" << sp1->_a2 << endl;

	chy::shared_ptr<A> sp5(new A);
	chy::shared_ptr<A> sp6(sp5);

	sp1 = sp5;
	sp2 = sp5;
	sp3 = sp5;

	// 自己给自己赋值
	chy::shared_ptr<int> sp4(new int);
	sp4 = sp4;
	sp1 = sp5;
}




// 定制删除器
void test_shared_ptr3()
{
	// 仿函数对象
	std::shared_ptr<Node> n1(new Node[5], chy::DeleteArray<Node>());
	std::shared_ptr<Node> n2(new Node);

	std::shared_ptr<int> n3(new int[5], chy::DeleteArray<int>());

	std::shared_ptr<int> n4((int*)malloc(sizeof(12)), chy::Free<int>());

	// //lambda
	//std::shared_ptr<Node> n1(new Node[5], [](Node* ptr){delete[] ptr; });
	//std::shared_ptr<Node> n2(new Node);

	//std::shared_ptr<int> n3(new int[5], [](int* ptr){delete[] ptr; });

	//std::shared_ptr<int> n4((int*)malloc(sizeof(12)), [](int* ptr){free(ptr); });
	//std::shared_ptr<file> n5(fopen("test.txt", "w"), [](file* ptr){fclose(ptr); });

	//shared_ptr支持在参数列表中传入 删除器对象以应对不同的情况

	//unqiue_ptr不支持在参数列表中传入 只能使用模板参数
	std::unique_ptr<Node, chy::DeleteArray<Node>> up(new Node[5]);
}




// 递归终止函数
template <class T>
void ShowList(const T& t)
{
	cout << t << endl;
}

// 展开函数
template <class T, class ...Args>
void ShowList(T value, Args... args)
{
	cout << value << " ";
	ShowList(args...);
}

int main()
{
	/*ShowList(1);
	ShowList(1, 'A');
	ShowList(1, 'A', std::string("sort"));*/
	//Test4();
	//test_auto_ptr();
	//test_unique_ptr();
	//test_shared_ptr1();
	test_shared_ptr3();
	return 0;
}